package com.common.www.controller.sale;

import com.common.www.aop.resolver.CurrentUser;
import com.common.www.bean.entity.Result;
import com.common.www.bean.entity.recycle.RecycleBill;
import com.common.www.bean.entity.recycle.RecycleBillTypeItem;
import com.common.www.bean.entity.sale.SaleBill;
import com.common.www.bean.entity.sale.SaleBillTypeItem;
import com.common.www.bean.vo.UserVo;
import com.common.www.service.auth.UserService;
import com.common.www.service.recycle.RecycleBillImgItemService;
import com.common.www.service.recycle.RecycleBillService;
import com.common.www.service.recycle.RecycleBillTypeItemService;
import com.common.www.service.recycle.RecycleTypeService;
import com.common.www.service.sale.SaleBillImgItemService;
import com.common.www.service.sale.SaleBillService;
import com.common.www.service.sale.SaleBillTypeItemService;
import com.common.www.service.sale.SaleFactoryService;
import com.common.www.utils.R;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * @author YangGS
 * @version 1.0
 * @date 2024/3/12 11:17
 */
@RestController
@CrossOrigin()
@Transactional
@RequestMapping(value = {"api/statistics"})
@Api(tags = "API 运营统计管理接口")
public class OperateStatisticsController {
    @Autowired
    private RecycleTypeService recycleTypeService;
    @Autowired
    private RecycleBillService recycleBillService;
    @Autowired
    private RecycleBillTypeItemService recycleBillTypeItemService;
    @Autowired
    private RecycleBillImgItemService recycleBillImgItemService;

    @Autowired
    private SaleBillImgItemService saleBillImgItemService;
    @Autowired
    private SaleBillTypeItemService saleBillTypeItemService;
    @Autowired
    private SaleBillService saleBillService;
    @Autowired
    private SaleFactoryService saleFactoryService;
    @Autowired
    private UserService userService;


    /**
     * 从时间维度获取司机端运营数据--饼状图
     *
     * @param type   1.日 2.月 3.年
     * @param start  输入时间前推5(日、月、年)
     * @param end    查询时间
     * @param userVo
     * @return
     * @throws ParseException
     */
    @ApiOperation("从时间维度获取司机端运营数据--饼状图")
    @PostMapping(value = "getDriverTimeIncome")
    public Result getDriverTimeIncomeDay(Integer type, String start, String end, @CurrentUser UserVo userVo) throws ParseException {
        List<SaleBill> saleBills = queryDriverFlow(type, start, end, userVo);

        List<SaleBillTypeItem> saleBillTypeItems = new ArrayList<>();
        BigDecimal countPriceActual = BigDecimal.ZERO;
        BigDecimal countWeightActual = BigDecimal.ZERO;
        for (SaleBill saleBill : saleBills) {
            countPriceActual = countPriceActual.add(saleBill.getPriceActual());
            countWeightActual = countWeightActual.add(saleBill.getWeightActual());
            for (SaleBillTypeItem typeItem : saleBill.getTypeList()) {
                if (typeItem.getLevel() == 2) {
                    saleBillTypeItems.add(typeItem);
                }
            }
        }

        Map<String, Object> backToMap = new HashMap<>();
        List<Map<String, Object>> weightList = new ArrayList<>();
        List<Map<String, Object>> incomeList = new ArrayList<>();
        Map<String, List<SaleBillTypeItem>> listMap = saleBillTypeItems.stream().collect(Collectors.groupingBy(saleBillTypeItem -> saleBillTypeItem.getName()));
        for (Map.Entry<String, List<SaleBillTypeItem>> item : listMap.entrySet()) {
            String name = item.getKey();
            List<SaleBillTypeItem> value = item.getValue();
            Map<String, Object> tempIncomeMap = new HashMap<>();
            Map<String, Object> tempWeightMap = new HashMap<>();

            BigDecimal tempPrice = BigDecimal.ZERO;
            BigDecimal tempWeight = BigDecimal.ZERO;
            for (SaleBillTypeItem tempItem : value) {
                if (tempItem.getPriceActual() == null) {
                    continue;
                }
                tempPrice = tempPrice.add(tempItem.getPriceActual());
                if (1 == tempItem.getUnitType()) {
                    BigDecimal weightActualInGrams = tempItem.getWeightActual().multiply(new BigDecimal(1000));
                    tempWeight = tempWeight.add(weightActualInGrams);
                } else {
                    tempWeight = tempWeight.add(tempItem.getWeightActual());
                }
            }
            tempIncomeMap.put("name", name);
            tempIncomeMap.put("countPrice", tempPrice);
            tempWeightMap.put("name", name);
            tempWeightMap.put("countWeight", tempWeight);
            incomeList.add(tempIncomeMap);
            weightList.add(tempWeightMap);
        }
        backToMap.put("countPriceActual", countPriceActual);
        backToMap.put("countWeightActual", countWeightActual);
        backToMap.put("weightList", weightList);
        backToMap.put("incomeList", incomeList);

        return R.ok(backToMap);
    }


    /**
     * 从时间维度获取司机端流水数据--柱状图
     *
     * @param type   1.日 2.月 3.年
     * @param start
     * @param end
     * @param userVo
     * @return
     */
    @ApiOperation("从时间维度获取司机端流水数据--柱状图")
    @PostMapping(value = "getDriverTimeDay")
    public Result getDriverTimeDay(Integer type, String start, String end, @CurrentUser UserVo userVo) throws ParseException {
        List<SaleBill> saleBills = queryDriverFlow(type, start, end, userVo);

        List<Map<String, Object>> backToMap = new ArrayList<>();
        // 根据type属性进行分组
        Map<Date, List<SaleBill>> groupedByTime = saleBills.stream()
                .collect(Collectors.groupingBy(SaleBill -> {
                    Date updateTime = SaleBill.getLastUpdateTime();
                    // 根据type属性决定分组的时间单位
                    if (type == 1) {
                        // 以日为准进行分组
                        return truncateToDate(updateTime);
                    } else if (type == 2) {
                        // 以月为准进行分组
                        return truncateToMonth(updateTime);
                    } else if (type == 3) {
                        // 以年为准进行分组
                        return truncateToYear(updateTime);
                    } else {
                        return updateTime;
                    }
                }));

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        // 输出分组结果
        for (Map.Entry<Date, List<SaleBill>> entry : groupedByTime.entrySet()) {
            Date time = entry.getKey();
            List<SaleBill> value = entry.getValue();
            BigDecimal tempPrice = BigDecimal.ZERO;
            BigDecimal tempWeight = BigDecimal.ZERO;
            for (SaleBill tempItem : value) {
                tempPrice = tempPrice.add(tempItem.getPriceActual());
                tempWeight = tempWeight.add(tempItem.getWeightActual());
            }
            Map<String, Object> tempMap = new HashMap<>();
            String formattedTime = dateFormat.format(time);
            tempMap.put("time", formattedTime);
            tempMap.put("countPrice", tempPrice);
            tempMap.put("countWeight", tempWeight);
            backToMap.add(tempMap);
        }

        return R.ok(backToMap);
    }

    /**
     * 从时间维度获取司机端流水数据--柱状图
     *
     * @param type   1.日 2.月 3.年
     * @param start
     * @param end
     * @param userVo
     * @return
     */
    @ApiOperation("从时间维度获取司机端流水数据--柱状图")
    @PostMapping(value = "getDriverTimeMonth")
    public Result getDriverTimeMonth(Integer type, String start, String end, @CurrentUser UserVo userVo) throws ParseException {
        List<SaleBill> saleBills = queryDriverFlow(type, start, end, userVo);

        List<Map<String, Object>> backToMap = new ArrayList<>();
        // 根据type属性进行分组
        Map<Date, List<SaleBill>> groupedByTime = saleBills.stream()
                .collect(Collectors.groupingBy(SaleBill -> {
                    Date updateTime = SaleBill.getLastUpdateTime();
                    // 根据type属性决定分组的时间单位
                    if (type == 1) {
                        // 以日为准进行分组
                        return truncateToDate(updateTime);
                    } else if (type == 2) {
                        // 以月为准进行分组
                        return truncateToMonth(updateTime);
                    } else if (type == 3) {
                        // 以年为准进行分组
                        return truncateToYear(updateTime);
                    } else {
                        return updateTime;
                    }
                }));

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
        // 输出分组结果
        for (Map.Entry<Date, List<SaleBill>> entry : groupedByTime.entrySet()) {
            Date time = entry.getKey();
            List<SaleBill> value = entry.getValue();
            BigDecimal tempPrice = BigDecimal.ZERO;
            BigDecimal tempWeight = BigDecimal.ZERO;
            for (SaleBill tempItem : value) {
                tempPrice = tempPrice.add(tempItem.getPriceActual());
                tempWeight = tempWeight.add(tempItem.getWeightActual());
            }
            Map<String, Object> tempMap = new HashMap<>();
            String formattedTime = dateFormat.format(time);
            tempMap.put("time", formattedTime);
            tempMap.put("countPrice", tempPrice);
            tempMap.put("countWeight", tempWeight);
            backToMap.add(tempMap);
        }
        return R.ok(backToMap);
    }

    /**
     * 从时间维度获取司机端流水数据--柱状图
     *
     * @param type   1.日 2.月 3.年
     * @param start
     * @param end
     * @param userVo
     * @return
     */
    @ApiOperation("从时间维度获取司机端流水数据--柱状图")
    @PostMapping(value = "getDriverTimeYear")
    public Result getDriverTimeYear(Integer type, String start, String end, @CurrentUser UserVo userVo) throws ParseException {
        List<SaleBill> saleBills = queryDriverFlow(type, start, end, userVo);

        List<Map<String, Object>> backToMap = new ArrayList<>();
        // 根据type属性进行分组
        Map<Date, List<SaleBill>> groupedByTime = saleBills.stream()
                .collect(Collectors.groupingBy(SaleBill -> {
                    Date updateTime = SaleBill.getLastUpdateTime();
                    // 根据type属性决定分组的时间单位
                    if (type == 1) {
                        // 以日为准进行分组
                        return truncateToDate(updateTime);
                    } else if (type == 2) {
                        // 以月为准进行分组
                        return truncateToMonth(updateTime);
                    } else if (type == 3) {
                        // 以年为准进行分组
                        return truncateToYear(updateTime);
                    } else {
                        return updateTime;
                    }
                }));

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy");
        // 输出分组结果
        for (Map.Entry<Date, List<SaleBill>> entry : groupedByTime.entrySet()) {
            Date time = entry.getKey();
            List<SaleBill> value = entry.getValue();
            BigDecimal tempPrice = BigDecimal.ZERO;
            BigDecimal tempWeight = BigDecimal.ZERO;
            for (SaleBill tempItem : value) {
                tempPrice = tempPrice.add(tempItem.getPriceActual());
                tempWeight = tempWeight.add(tempItem.getWeightActual());
            }
            Map<String, Object> tempMap = new HashMap<>();
            String formattedTime = dateFormat.format(time);
            tempMap.put("time", formattedTime);
            tempMap.put("countPrice", tempPrice);
            tempMap.put("countWeight", tempWeight);
            backToMap.add(tempMap);
        }

        return R.ok(backToMap);
    }


    /**
     * 流水查询
     *
     * @param type
     * @param start
     * @param end
     * @param userVo
     * @return
     */
    private List<SaleBill> queryDriverFlow(Integer type, String start, String end, UserVo userVo) throws ParseException {
        HashMap hashMap = new HashMap();
        //已完成的卖出单
        HashMap temp1HashMap = new HashMap();
        temp1HashMap.put("payType", 10);
        List<SaleBill> item1List = saleBillService.getList(temp1HashMap, null);
        Long[] ids1 = new Long[item1List.size()];
        for (int i = 0; i < item1List.size(); i++) {
            ids1[i] = item1List.get(i).getId();
        }

        HashMap temp2HashMap = new HashMap();
        Integer[] commonValues = {1, 2, 3};
        temp2HashMap.put("payType_in", commonValues);
        temp2HashMap.put("periodStatus_ge", 100);
        List<SaleBill> item2List = saleBillService.getList(temp2HashMap, null);
        Long[] ids2 = new Long[item2List.size()];
        Long[] ids = new Long[item1List.size() + item2List.size()];
        for (int i = 0; i < item2List.size(); i++) {
            ids2[i] = item2List.get(i).getId();
        }

        System.arraycopy(ids1, 0, ids, 0, ids1.length);
        System.arraycopy(ids2, 0, ids, ids1.length, ids2.length);
        if (ids.length > 0) {
            hashMap.put("id_in", ids);
        }

        // 获取当前日期
        LocalDate currentDate = LocalDate.now(ZoneId.systemDefault());
        // 定义日期时间格式化器
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 当前日向前推5天的起始日期和时间（00:00:00）
        LocalDateTime startOfDay = currentDate.minusDays(5).atStartOfDay();
        LocalDateTime endOfDay = currentDate.atTime(23, 59, 59);
        // 当前月向前推5月的起始日期和时间（第一天的00:00:00）
        LocalDateTime startOfMonth = currentDate.minusMonths(5).withDayOfMonth(1).atStartOfDay();
        LocalDateTime endOfMonth = currentDate.atTime(23, 59, 59);
        // 当前年向前推5年的起始日期和时间（1月1日的00:00:00）
        LocalDateTime startOfYear = currentDate.minusYears(5).withDayOfYear(1).atStartOfDay();
        LocalDateTime endOfYear = currentDate.atTime(23, 59, 59);
        // 格式化日期时间为字符串
        String startOfDayStr = startOfDay.format(dateTimeFormatter);
        String endOfDayStr = endOfDay.format(dateTimeFormatter);
        String startOfMonthStr = startOfMonth.format(dateTimeFormatter);
        String endOfMonthStr = endOfMonth.format(dateTimeFormatter);
        String startOfYearStr = startOfYear.format(dateTimeFormatter);
        String endOfYearStr = endOfYear.format(dateTimeFormatter);

        LocalDate localDate = null;
        if (end != null) {
            // 去掉时区信息
            String endWithoutTimezone = end.replaceAll("GMT.*$", "").trim();

            // 创建DateTimeFormatter并解析时间字符串
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM dd yyyy HH:mm:ss", Locale.ENGLISH);
            localDate = LocalDate.parse(endWithoutTimezone, formatter);
        }

        if (type == 1) {
            if (end != null) {
                start = localDate.minusDays(5).atStartOfDay().format(dateTimeFormatter);
                end = localDate.atTime(23, 59, 59).format(dateTimeFormatter);
                hashMap.put("lastUpdateTime_ge", start);
                hashMap.put("lastUpdateTime_le", end);
            } else {
                hashMap.put("lastUpdateTime_ge", startOfDayStr);
                hashMap.put("lastUpdateTime_le", endOfDayStr);
            }
        } else if (type == 2) {
            if (end != null) {
                start = localDate.minusMonths(5).withDayOfMonth(1).atStartOfDay().format(dateTimeFormatter);
                end = localDate.atTime(23, 59, 59).format(dateTimeFormatter);
                hashMap.put("lastUpdateTime_ge", start);
                hashMap.put("lastUpdateTime_le", end);
            } else {
                hashMap.put("lastUpdateTime_ge", startOfMonthStr);
                hashMap.put("lastUpdateTime_le", endOfMonthStr);
            }
        } else if (type == 3) {
            if (end != null) {
                start = localDate.minusYears(5).withDayOfYear(1).atStartOfDay().format(dateTimeFormatter);
                end = localDate.atTime(23, 59, 59).format(dateTimeFormatter);
                hashMap.put("lastUpdateTime_ge", start);
                hashMap.put("lastUpdateTime_le", end);
            } else {
                hashMap.put("lastUpdateTime_ge", startOfYearStr);
                hashMap.put("lastUpdateTime_le", endOfYearStr);
            }
        }
        if (userVo != null) {
            hashMap.put("createUser.id", userVo.getId());
        }
        //以卖出单数据为统计依据
        List<SaleBill> saleBills = saleBillService.getList(hashMap, null);
        return saleBills;
    }


    /**
     * 将Date截断到天
     *
     * @param date
     * @return
     */
    private static Date truncateToDate(Date date) {
        // 将Date转换为LocalDate，然后截断时间，再转换回Date
        LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        Instant truncatedInstant = localDate.atStartOfDay(ZoneId.systemDefault()).toInstant();
        return Date.from(truncatedInstant);
    }

    /**
     * 将Date截断到月
     *
     * @param date
     * @return
     */
    private static Date truncateToMonth(Date date) {
        // 将Date转换为YearMonth，然后截断时间，再转换回Date
        YearMonth yearMonth = YearMonth.from(date.toInstant().atZone(ZoneId.systemDefault()));
        LocalDate localDate = yearMonth.atDay(1);
        Instant truncatedInstant = localDate.atStartOfDay(ZoneId.systemDefault()).toInstant();
        return Date.from(truncatedInstant);
    }

    /**
     * 将Date截断到年
     *
     * @param date
     * @return
     */
    private static Date truncateToYear(Date date) {
        // 将Date转换为Year，然后截断时间，再转换回Date
        LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate firstDayOfYear = LocalDate.of(localDate.getYear(), 1, 1);
        Instant truncatedInstant = firstDayOfYear.atStartOfDay(ZoneId.systemDefault()).toInstant();
        return Date.from(truncatedInstant);
    }


    /**
     * 从时间维度获取司机端运营数据--饼状图
     *
     * @param type   1.日 2.月 3.年
     * @param start  输入时间前推5(日、月、年)
     * @param end    查询时间
     * @param userVo
     * @return
     * @throws ParseException
     */
    @ApiOperation("从时间维度获取企业端运营数据--饼状图")
    @PostMapping(value = "getEnterpriseTimeIncome")
    public Result getEnterpriseTimeIncomeDay(Integer type, String start, String end, @CurrentUser UserVo userVo) throws ParseException {
        List<RecycleBill> recycleBills = queryEnterpriseFlow(type, start, end, userVo);

        List<RecycleBillTypeItem> recycleBillTypeItems = new ArrayList<>();
        BigDecimal countPriceActual = BigDecimal.ZERO;
        BigDecimal countWeightActual = BigDecimal.ZERO;
        for (RecycleBill recycleBill : recycleBills) {
            countPriceActual = countPriceActual.add(recycleBill.getPriceActual());
            countWeightActual = countWeightActual.add(recycleBill.getWeightActual());
            for (RecycleBillTypeItem typeItem : recycleBill.getTypeList()) {
                if (typeItem.getLevel() == 2) {
                    recycleBillTypeItems.add(typeItem);
                }
            }
        }

        Map<String, Object> backToMap = new HashMap<>();
        List<Map<String, Object>> weightList = new ArrayList<>();
        List<Map<String, Object>> incomeList = new ArrayList<>();
        Map<String, List<RecycleBillTypeItem>> listMap = recycleBillTypeItems.stream().collect(Collectors.groupingBy(recycleBillTypeItem -> recycleBillTypeItem.getName()));
        for (Map.Entry<String, List<RecycleBillTypeItem>> item : listMap.entrySet()) {
            String name = item.getKey();
            List<RecycleBillTypeItem> value = item.getValue();
            Map<String, Object> tempIncomeMap = new HashMap<>();
            Map<String, Object> tempWeightMap = new HashMap<>();

            BigDecimal tempPrice = BigDecimal.ZERO;
            BigDecimal tempWeight = BigDecimal.ZERO;
            for (RecycleBillTypeItem tempItem : value) {
                tempPrice = tempPrice.add(tempItem.getPriceActual());
                if (1 == tempItem.getUnitType()) {
                    BigDecimal weightActualInGrams = tempItem.getWeightActual().multiply(new BigDecimal(1000));
                    tempWeight = tempWeight.add(weightActualInGrams);
                } else {
                    tempWeight = tempWeight.add(tempItem.getWeightActual());
                }
            }
            tempIncomeMap.put("name", name);
            tempIncomeMap.put("countPrice", tempPrice);
            tempWeightMap.put("name", name);
            tempWeightMap.put("countWeight", tempWeight);
            incomeList.add(tempIncomeMap);
            weightList.add(tempWeightMap);
        }
        backToMap.put("countPriceActual", countPriceActual);
        backToMap.put("countWeightActual", countWeightActual);
        backToMap.put("weightList", weightList);
        backToMap.put("incomeList", incomeList);

        return R.ok(backToMap);
    }


    /**
     * 从时间维度获取企业端流水数据--柱状图
     *
     * @param type   1.日 2.月 3.年
     * @param start
     * @param end
     * @param userVo
     * @return
     */
    @ApiOperation("从时间维度获取企业端流水数据--柱状图")
    @PostMapping(value = "getEnterpriseTimeDay")
    public Result getEnterpriseTimeDay(Integer type, String start, String end, @CurrentUser UserVo userVo) throws ParseException {
        List<RecycleBill> recycleBills = queryEnterpriseFlow(type, start, end, userVo);

        List<Map<String, Object>> backToMap = new ArrayList<>();
        // 根据type属性进行分组
        Map<Date, List<RecycleBill>> groupedByTime = recycleBills.stream()
                .collect(Collectors.groupingBy(RecycleBill -> {
                    Date updateTime = RecycleBill.getLastUpdateTime();
                    // 根据type属性决定分组的时间单位
                    if (type == 1) {
                        // 以日为准进行分组
                        return truncateToDate(updateTime);
                    } else if (type == 2) {
                        // 以月为准进行分组
                        return truncateToMonth(updateTime);
                    } else if (type == 3) {
                        // 以年为准进行分组
                        return truncateToYear(updateTime);
                    } else {
                        return updateTime;
                    }
                }));

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        // 输出分组结果
        for (Map.Entry<Date, List<RecycleBill>> entry : groupedByTime.entrySet()) {
            Date time = entry.getKey();
            List<RecycleBill> value = entry.getValue();
            BigDecimal tempPrice = BigDecimal.ZERO;
            BigDecimal tempWeight = BigDecimal.ZERO;
            for (RecycleBill tempItem : value) {
                tempPrice = tempPrice.add(tempItem.getPriceActual());
                tempWeight = tempWeight.add(tempItem.getWeightActual());
            }
            Map<String, Object> tempMap = new HashMap<>();
            String formattedTime = dateFormat.format(time);
            tempMap.put("time", formattedTime);
            tempMap.put("countPrice", tempPrice);
            tempMap.put("countWeight", tempWeight);
            backToMap.add(tempMap);
        }

        return R.ok(backToMap);
    }

    /**
     * 从时间维度获取企业端流水数据--柱状图
     *
     * @param type   1.日 2.月 3.年
     * @param start
     * @param end
     * @param userVo
     * @return
     */
    @ApiOperation("从时间维度获取企业端流水数据--柱状图")
    @PostMapping(value = "getEnterpriseTimeMonth")
    public Result getEnterpriseTimeMonth(Integer type, String start, String end, @CurrentUser UserVo userVo) throws ParseException {
        List<RecycleBill> recycleBills = queryEnterpriseFlow(type, start, end, userVo);

        List<Map<String, Object>> backToMap = new ArrayList<>();
        // 根据type属性进行分组
        Map<Date, List<RecycleBill>> groupedByTime = recycleBills.stream()
                .collect(Collectors.groupingBy(RecycleBill -> {
                    Date updateTime = RecycleBill.getLastUpdateTime();
                    // 根据type属性决定分组的时间单位
                    if (type == 1) {
                        // 以日为准进行分组
                        return truncateToDate(updateTime);
                    } else if (type == 2) {
                        // 以月为准进行分组
                        return truncateToMonth(updateTime);
                    } else if (type == 3) {
                        // 以年为准进行分组
                        return truncateToYear(updateTime);
                    } else {
                        return updateTime;
                    }
                }));

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
        // 输出分组结果
        for (Map.Entry<Date, List<RecycleBill>> entry : groupedByTime.entrySet()) {
            Date time = entry.getKey();
            List<RecycleBill> value = entry.getValue();
            BigDecimal tempPrice = BigDecimal.ZERO;
            BigDecimal tempWeight = BigDecimal.ZERO;
            for (RecycleBill tempItem : value) {
                tempPrice = tempPrice.add(tempItem.getPriceActual());
                tempWeight = tempWeight.add(tempItem.getWeightActual());
            }
            Map<String, Object> tempMap = new HashMap<>();
            String formattedTime = dateFormat.format(time);
            tempMap.put("time", formattedTime);
            tempMap.put("countPrice", tempPrice);
            tempMap.put("countWeight", tempWeight);
            backToMap.add(tempMap);
        }
        return R.ok(backToMap);
    }

    /**
     * 从时间维度获取企业端流水数据--柱状图
     *
     * @param type   1.日 2.月 3.年
     * @param start
     * @param end
     * @param userVo
     * @return
     */
    @ApiOperation("从时间维度获取企业端流水数据--柱状图")
    @PostMapping(value = "getEnterpriseTimeYear")
    public Result getEnterpriseTimeYear(Integer type, String start, String end, @CurrentUser UserVo userVo) throws ParseException {
        List<RecycleBill> recycleBills = queryEnterpriseFlow(type, start, end, userVo);

        List<Map<String, Object>> backToMap = new ArrayList<>();
        // 根据type属性进行分组
        Map<Date, List<RecycleBill>> groupedByTime = recycleBills.stream()
                .collect(Collectors.groupingBy(RecycleBill -> {
                    Date updateTime = RecycleBill.getLastUpdateTime();
                    // 根据type属性决定分组的时间单位
                    if (type == 1) {
                        // 以日为准进行分组
                        return truncateToDate(updateTime);
                    } else if (type == 2) {
                        // 以月为准进行分组
                        return truncateToMonth(updateTime);
                    } else if (type == 3) {
                        // 以年为准进行分组
                        return truncateToYear(updateTime);
                    } else {
                        return updateTime;
                    }
                }));

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy");
        // 输出分组结果
        for (Map.Entry<Date, List<RecycleBill>> entry : groupedByTime.entrySet()) {
            Date time = entry.getKey();
            List<RecycleBill> value = entry.getValue();
            BigDecimal tempPrice = BigDecimal.ZERO;
            BigDecimal tempWeight = BigDecimal.ZERO;
            for (RecycleBill tempItem : value) {
                tempPrice = tempPrice.add(tempItem.getPriceActual());
                tempWeight = tempWeight.add(tempItem.getWeightActual());
            }
            Map<String, Object> tempMap = new HashMap<>();
            String formattedTime = dateFormat.format(time);
            tempMap.put("time", formattedTime);
            tempMap.put("countPrice", tempPrice);
            tempMap.put("countWeight", tempWeight);
            backToMap.add(tempMap);
        }

        return R.ok(backToMap);
    }


    /**
     * 流水查询
     *
     * @param type
     * @param start
     * @param end
     * @param userVo
     * @return
     */
    private List<RecycleBill> queryEnterpriseFlow(Integer type, String start, String end, UserVo userVo) throws ParseException {
        HashMap hashMap = new HashMap();
        //已完成的回收单
        Integer[] commonValues = {10, 11};
        hashMap.put("status_in", commonValues);

        // 获取当前日期
        LocalDate currentDate = LocalDate.now(ZoneId.systemDefault());
        // 定义日期时间格式化器
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 当前日向前推5天的起始日期和时间（00:00:00）
        LocalDateTime startOfDay = currentDate.minusDays(5).atStartOfDay();
        LocalDateTime endOfDay = currentDate.atTime(23, 59, 59);
        // 当前月向前推5月的起始日期和时间（第一天的00:00:00）
        LocalDateTime startOfMonth = currentDate.minusMonths(5).withDayOfMonth(1).atStartOfDay();
        LocalDateTime endOfMonth = currentDate.atTime(23, 59, 59);
        // 当前年向前推5年的起始日期和时间（1月1日的00:00:00）
        LocalDateTime startOfYear = currentDate.minusYears(5).withDayOfYear(1).atStartOfDay();
        LocalDateTime endOfYear = currentDate.atTime(23, 59, 59);
        // 格式化日期时间为字符串
        String startOfDayStr = startOfDay.format(dateTimeFormatter);
        String endOfDayStr = endOfDay.format(dateTimeFormatter);
        String startOfMonthStr = startOfMonth.format(dateTimeFormatter);
        String endOfMonthStr = endOfMonth.format(dateTimeFormatter);
        String startOfYearStr = startOfYear.format(dateTimeFormatter);
        String endOfYearStr = endOfYear.format(dateTimeFormatter);

        LocalDate localDate = null;
        if (end != null) {
            // 去掉时区信息
            String endWithoutTimezone = end.replaceAll("GMT.*$", "").trim();

            // 创建DateTimeFormatter并解析时间字符串
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM dd yyyy HH:mm:ss", Locale.ENGLISH);
            localDate = LocalDate.parse(endWithoutTimezone, formatter);
        }

        if (type == 1) {
            if (end != null) {
                start = localDate.minusDays(5).atStartOfDay().format(dateTimeFormatter);
                end = localDate.atTime(23, 59, 59).format(dateTimeFormatter);
                hashMap.put("lastUpdateTime_ge", start);
                hashMap.put("lastUpdateTime_le", end);
            } else {
                hashMap.put("lastUpdateTime_ge", startOfDayStr);
                hashMap.put("lastUpdateTime_le", endOfDayStr);
            }
        } else if (type == 2) {
            if (end != null) {
                start = localDate.minusMonths(5).withDayOfMonth(1).atStartOfDay().format(dateTimeFormatter);
                end = localDate.atTime(23, 59, 59).format(dateTimeFormatter);
                hashMap.put("lastUpdateTime_ge", start);
                hashMap.put("lastUpdateTime_le", end);
            } else {
                hashMap.put("lastUpdateTime_ge", startOfMonthStr);
                hashMap.put("lastUpdateTime_le", endOfMonthStr);
            }
        } else if (type == 3) {
            if (end != null) {
                start = localDate.minusYears(5).withDayOfYear(1).atStartOfDay().format(dateTimeFormatter);
                end = localDate.atTime(23, 59, 59).format(dateTimeFormatter);
                hashMap.put("lastUpdateTime_ge", start);
                hashMap.put("lastUpdateTime_le", end);
            } else {
                hashMap.put("lastUpdateTime_ge", startOfYearStr);
                hashMap.put("lastUpdateTime_le", endOfYearStr);
            }
        }
        if (userVo != null) {
            hashMap.put("createUser.id", userVo.getId());
        }
        //以卖出单数据为统计依据
        List<RecycleBill> recycleBills = recycleBillService.getList(hashMap, null);
        return recycleBills;
    }


}
